package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Vector;

import modelo.Factura;
import modelo.ItemFactura;
import modelo.Usuario;

public class DAOFactura {
private static DAOFactura instancia;
	
	private DAOFactura()
	{
		
	}
	public static DAOFactura getInstancia()
	{
		if (instancia == null)
			instancia = new DAOFactura();
		return instancia;
	}
	//guardo las facturas en la base, no es necesario meterlas en el vector
	//si las necesito las busco en la base y la agrego al vector.
	
	//hay que hacer un listar y un agregar, el listar tiene que devolver un vector de facturas

	//VARIABLE PARA GUARDAR LAS FACTURAS EN LA BASE
	private static String INSERT ="insert into facturas (fecha, importe, medicionactual, id_usuario) values(?,?,?,?)";
	
	
	//VARIABLE PARA REALIZAR LA CONSULTA de fact
	private static final String CONSULTA="select nroFac, fecha, importe, medicionactual, id_Factura from facturas where nroFac= ?";
	
	private static final String MAXIMO_NRO = "select max(nroFac) as ultimo from facturas";


/**
* Guarda un nuevo Factura INDUSTRIAL en la base Factura
* @param factura
* @return true si no hubo errores, false caso contrario
*/
@SuppressWarnings("deprecation")
public boolean guardar(Factura factura)
{
	
		//OBTENGO LA CONEXION
		
		Connection conn= PoolConexiones.getPoolConnection().getConnection();
		
		//VERIFICAMOS QUE LA CONEXION FUE CORRECTA
	
			if(conn!=null){
			  try {
				//CREO UN OBJETO QUE REPRESENTA LA CONSULTA SQL
				 PreparedStatement s;
				 //LE PASO EL INSERT
				 s= conn.prepareStatement(INSERT);
				//LE PASAMOS LOS DATOS AL INSERT, EN EL ORDEN
				//QUE DECLARAMOS EN LA CONSTANTE
					
				 java.sql.Date fecha=new java.sql.Date(factura.getFecha().getTime());
				 s.setDate(1, fecha);
				 s.setFloat(2, factura.getImporte());
				 s.setFloat(3, factura.getMedicionactual());
				 s.setInt(4, factura.getNroCli());
					
				  //EJECUTAMOS EL QUERY
				  int registrosguardados = s.executeUpdate();
				  int nroFac=this.getUltimoNroPersistido();
				  //CERRAMOS EL QUERY REPRESENTADO POR S
				  s.close();
						 
				 //VERIFICAMOS QUE HAYA GUARDADO UN REGISTRO y cargamos los items
				if (registrosguardados>0)
				{
					DAOItemFactura.getInstancia().guardar(factura.getItems(), nroFac);
					return true;					
				}
				else
				{
					return false;
					
				}
			 }
			 catch (SQLException e) {
				 
				 System.err.print("No se pudo guardar la Factura");
				 e.printStackTrace();
				 return false;
				 
			}
			finally{
				try{
					//CERRAMOS LA CONEXION
					PoolConexiones.getPoolConnection().releaseConnection(conn);
			
				}
			   
				catch(Exception e){
				   System.err.print("No se pudo cerrar la conexion");
				   e.printStackTrace();
				   return false;
			   }
			}
		
		}//if
	//NO SE PUDO REALIZAR LA CONEXION
	else{
		return false;
		}
}

/**
* Cargamos todas las facturas en un vector
* 
* @param Factura
* @return
*/
public Vector<Factura> listar(int nroFactura){
	
	//CREO EL VECTOR QUE VOY A DEVOLVER
	Vector<Factura> facturas=new Vector<Factura>();
	
	//OBTENGO LA CONEXION
	Connection conn= PoolConexiones.getPoolConnection().getConnection();
	
	//VERIFICAMOS QUE LA CONEXION FUE CORRECTA
	if (conn!=null){
		try{
			//CREO UN OBJETO QUE REPRESENTA A UN CONSULTA SQL
			PreparedStatement s;
			//ARMO LA CONSULTA
			s=conn.prepareStatement(CONSULTA);
			s.setInt (1, nroFactura);
			
			
			//EJECUTO LA CONSULTA(guardo la cantidad de registros)
			//ResultSet es un cursor, asi que lo empiezo a recorrer
			//Este metodo asegura que nunca es Nulo
			ResultSet result=s.executeQuery();
			
			//Recorre los registro de la consulta
			//hasta llegar al final
			while (result.next()){
				
				int nroFac			= 	result.getInt("nroFac");
				Date fecha		=	result.getDate("fecha");
				float importe	=	result.getFloat("importe");
				float medicionactual	=	result.getFloat("medicionactual");
				int id_usuario		=	result.getInt("id_usuario");
				
					
				//Creo un nuevo Factura, y le paso los datos obtenidos en la
				//consulta realizada.
				Factura auxFact=new Factura(null);
				Usuario auxUsuario=null;
				auxFact.setNroFac(nroFac);
				auxFact.setFecha(fecha);
				auxFact.setImporte(importe);
				auxFact.setMedicionActual(medicionactual);
				
				auxFact.setCliente(DAOUIndustrial.buscar(id_usuario).elementAt(0)); //si no existe usuario industrial entonces tiene que ser residencial
				if (auxFact.getCliente()==null) auxFact.setCliente(DAOUResidencial.buscar(id_usuario).elementAt(0));
				
				//Cargamos los items
				DAOItemFactura.getInstancia().listar(nroFactura, auxFact.getItems());
				
			//Agrego al vector el Factura obtenido
				facturas.add(auxFact);
			}//while
			
			//Cierro el cursor
			result.close();
			
			//CERRAMOS EL QUERY
			s.close();

			//Devuelvo el Vector con el Factura
			return facturas;
			
		}
		catch(Exception e){
			System.err.print("NO SE PUDO REALIZAR LA CONSULTA");
			e.printStackTrace();
			return null;
		}
		finally{
				//Si se pudo realizar la conexion, realiza la liberacion de 
				//la misma.
				if (conn!=null){
				 PoolConexiones.getPoolConnection().releaseConnection(conn);
				 
			 }
		}
	}
	else{
		System.out.print("NO SE PUDO REALIZAR LA CONEXION");
		return null;
	}
	
}
public Integer getUltimoNroPersistido(){
	Connection conn= PoolConexiones.getPoolConnection().getConnection();
	Integer ultimo = 1;
	
	//VERIFICAMOS QUE LA CONEXION FUE CORRECTA
	if (conn!=null){
		try{
			//CREO UN OBJETO QUE REPRESENTA A UN CONSULTA SQL
			PreparedStatement s;
			//ARMO LA CONSULTA
			s=conn.prepareStatement(MAXIMO_NRO);
			
			ResultSet resultado = s.executeQuery();
			if (resultado.next()){
				ultimo = resultado.getInt("ultimo");
			}
			
			resultado.close();
			s.close();
		}
		catch (Exception e){
			ultimo = 1;
			e.printStackTrace();
		}
		
		finally{
			if (conn!=null){
				 PoolConexiones.getPoolConnection().releaseConnection(conn);
			 }
		}		
		
		return ultimo;
	}
	
	else{
		System.err.println("NO SE PUDO REALIZAR LA CONEXION");
		return null;
	}
}		

}
